using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data.SQLite;
using System.Drawing;
using System.Linq;
using System.Text;
using Jonathan.Classes;
using System.Windows.Forms;
using System.Threading;

namespace Jonathan.Controls
{
   /// <summary>
   /// Delegate to add an Item to the Reference list.
   /// </summary>
   /// <param name="item"></param>
   public delegate void DelAddRefItem (string item);

   /// <summary>
   /// Delegate to perform actions after the reference list is fully loaded.
   /// </summary>
   public delegate void DelRefLoaded ();

   /// <summary>
   /// A Control that will Display the different Texts Jonathan handles.
   /// </summary>
   public partial class CtrlReader : Tabber.TabberPage, IWebberHost
   {
      private string m_Abbrevation;
      private readonly FrmMain m_FormMain;
      private string m_Type;
      private ToolStripMenuItem m_TsmiAdd;
      private readonly List<CjData.IcDbInfo> m_Versions;
      private List<CPassage> m_Passages;
      private readonly bool m_Tsk;
      private readonly DelAddRefItem m_AddRef;
      private readonly DelRefLoaded m_RefLoaded;
      private bool m_Loaded;
      private bool m_HasSubBooks;

      private readonly SQLiteConnection m_DbConn;

      #region - Constructor -

      /// <summary>
      /// Creates a new Reader Control.
      /// </summary>
      /// <param name="main">Reference to Main Form.</param>
      /// <param name="version">Version of text to load.</param>
      /// <param name="filePath">Path to version.</param>
      public CtrlReader (FrmMain main, string version, string filePath)
         : base (version)
      {
         this.m_FormMain = main;
         this.m_Loaded = false;
         this.m_DbConn = new SQLiteConnection(Common.ConnString (filePath));
         this.Disposed += CtrlReaderDisposed;
         this.GetBookType ();
         InitializeComponent (main);

         this._Working.Visible = false;
         this.splitContainer1.Panel2.Resize += ReaderPanelResize;
         this.Load += CtrlReaderLoad;
         this.m_Versions = new List<CjData.IcDbInfo> { new CjData.IcDbInfo (filePath, version) };
         this.m_Passages = null;
         this.m_AddRef = new DelAddRefItem (this.AddRefWord);
         this.m_RefLoaded = new DelRefLoaded (this.RefLoaded);
         this.TabButton.ButtonToolTip = version;

         ColorPicker.ToolStripColorDropDown colorDd = new ColorPicker.ToolStripColorDropDown ();
         colorDd.ColorPicker.SelectedColorChanged += ForeColorPickerSelectedColorChanged;
         this._ForeColorPicker.ButtonClick += ForeColorPickerSelectedColorChanged;
         this._ForeColorPicker.DropDown = colorDd;
         ColorPicker.ToolStripColorDropDown colorDd2 = new ColorPicker.ToolStripColorDropDown ();
         colorDd2.ColorPicker.Color = Color.Yellow;
         colorDd2.ColorPicker.SelectedColorChanged += BackColorPickerSelectedColorChanged;
         this._BackColorPicker.ButtonClick += BackColorPickerSelectedColorChanged;
         this._BackColorPicker.DropDown = colorDd2;

         if (this.m_Type.Equals (Common.TYPE_BIBLE, StringComparison.CurrentCultureIgnoreCase))
         {
            this.SetupVersions (version, filePath);

            // Check for Treasury of Scripture Knowledge...
            this.m_Tsk = (this.m_FormMain.ProgramData.Tsk != null);
         }
         else
         {
            // This is not a bible...
            this.m_tsddVersions.Text = version;
            this.m_tsddVersions.Enabled = false;
            this.toolStripLabel1.Visible = false;
            this.btnQJGo.Visible = false;
            this.txtQJ.Visible = false;
            this.toolStripSeparator2.Visible = false;
            this.m_List.ShowPlusMinus = false;
            this.m_List.ShowRootLines = false;

            if (this.m_Type == Common.TYPE_REFERENCE)
            {
               this.m_RefList.BringToFront ();
               this.m_RefList.AllowMutltipleSelection = true;
               this.m_RefList.Visible = true;
               this.m_List.Visible = false;
               this.m_RefList.SelectedItemChange += RefListSelection;
            }
         }

         // Events...
         this.m_txtFind.KeyDown += FindKeyDown;
         this.txtQJ.KeyDown += QuickJumpKeyDown;
         this.m_List.AfterSelect += MListAfterSelect;
         this.m_WebMain.SetupWebber (main, this);
         this.m_WebSplit.SetupWebber (main, this);
      }

      private void CtrlReaderDisposed (object sender, EventArgs e)
      {
         this.m_DbConn.Dispose ();
      }

      /// <summary>
      /// Occurs when the Reader Panel is resized.
      /// </summary>
      /// <param name="sender">Reader Panel.</param>
      /// <param name="e">Event Arguments.</param>
      void ReaderPanelResize (object sender, EventArgs e)
      {
         this._Working.Top = this.splitContainer1.Panel2.Bottom - this._Working.Height - this.m_tsFind.Height - 10;
         this._Working.Left = (this.splitContainer1.Panel2.Width / 2) - (this._Working.Width / 2);
      }

      /// <summary>
      /// Occurs when this control is fully loaded.
      /// </summary>
      /// <param name="sender">This control.</param>
      /// <param name="e">Event Arguments.</param>
      void CtrlReaderLoad (object sender, EventArgs e)
      {
         this.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
         if (!this.m_Loaded)
            this.LoadBookList (true);
      }

      #endregion

      #region - Get Data -

      /// <summary>
      /// Gets the Type of Book...
      /// </summary>
      private void GetBookType ()
      {
         this.m_DbConn.Open ();
         SQLiteCommand command = this.m_DbConn.CreateCommand ();
         command.CommandText = "SELECT Type, HasSubBooks FROM book_info";
         SQLiteDataReader reader = command.ExecuteReader ();
         reader.Read ();
         this.m_Type = reader.GetString (0);
         this.m_HasSubBooks = Convert.ToBoolean(reader.GetInt32 (1));
         this.m_DbConn.Close ();
      }

      /// <summary>
      /// Gets the Abbreviations for the bibles...
      /// </summary>
      private void GetBibleAbbrev ()
      {
         this.m_Abbrevation = "";
         string toolTip = "";
         foreach (CjData.IcDbInfo dbI in this.m_Versions)
         {
            this.m_DbConn.Open ();
            SQLiteCommand command = this.m_DbConn.CreateCommand ();
            command.CommandText = "SELECT Abbreviation FROM book_info";
            SQLiteDataReader reader = command.ExecuteReader ();
            reader.Read ();

            toolTip += dbI.Name + " | ";
            if (!string.IsNullOrEmpty (this.m_Abbrevation))
            {
               this.m_Abbrevation += ", ";
            }
            this.m_Abbrevation += reader.GetString (0);
            this.m_DbConn.Close ();
         }
         toolTip = toolTip.Trim ().TrimEnd (new [] { '|' }).Trim ();
         this.ToolTip = toolTip;
      }

      /// <summary>
      /// Gets the string representation of the preface(s)...
      /// </summary>
      /// <returns>String of preface info..</returns>
      private string GetPreface ()
      {
         StringBuilder sb = new StringBuilder ();
         sb.Append ("<tr>");
         int w = 100 / this.m_Versions.Count;
         foreach (CjData.IcDbInfo dbI in this.m_Versions)
         {
            using (SQLiteConnection dbConn = new SQLiteConnection (Common.ConnString (dbI.Path)))
            {
               dbConn.Open ();
               SQLiteCommand command = dbConn.CreateCommand ();
               command.CommandText = "SELECT Summary FROM book_info";
               SQLiteDataReader reader = command.ExecuteReader ();
               reader.Read ();
               sb.Append ("<td width=\"" + w + "%\">");
               sb.Append (reader.GetString (0));
               sb.Append ("</td>");
            }
         }
         sb.Append ("</tr>");

         return sb.ToString ();
      }

      #endregion

      #region - Versioning -

      /// <summary>
      /// Sets up the initial version list...
      /// </summary>
      /// <param name="version">Starting version...</param>
      /// <param name="path">Path to version db...</param>
      private void SetupVersions (string version, string path)
      {
         ToolStripMenuItem tsmi = new ToolStripMenuItem (version) {Name = version, Tag = path};

         ToolStripMenuItem tsmiRemove = new ToolStripMenuItem ("Remove Version") {Name = "Remove"};
         tsmiRemove.Click += RemoveVersionClick;
         tsmi.DropDownItems.Add (tsmiRemove);
         ToolStripMenuItem tsmiChange = new ToolStripMenuItem ("Change Version") {Name = "Change"};
         tsmi.DropDownItems.Add (tsmiChange);

         this.m_tsddVersions.DropDownItems.Add (tsmi);
         this.m_tsddVersions.DropDownItems.Add (new ToolStripSeparator ());

         m_TsmiAdd = new ToolStripMenuItem ("Add Version");
         this.m_tsddVersions.DropDownOpening += VersionDropDownOpening;
         this.m_tsddVersions.DropDownItems.Add (m_TsmiAdd);
      }

      /// <summary>
      /// Occurs when opening the version dropdown...
      /// </summary>
      /// <param name="sender">ToolStripDropDownButton</param>
      /// <param name="e">Events</param>
      void VersionDropDownOpening (object sender, EventArgs e)
      {
         this.m_TsmiAdd.DropDownItems.Clear ();
         foreach (CjData.IcDbInfo dbI in this.m_FormMain.ProgramData.BibleDatabases)
         {
            if (!this.m_tsddVersions.DropDownItems.ContainsKey (dbI.Name))
            {
               ToolStripMenuItem tsmi = new ToolStripMenuItem (dbI.Name) {Tag = Common.DataFolder + dbI.Path};
               tsmi.Click += AddVersionClick;
               this.m_TsmiAdd.DropDownItems.Add (tsmi);
            }
         }

         CheckChangeRemoveVersion ();

         this.m_TsmiAdd.Enabled = this.m_TsmiAdd.DropDownItems.Count != 0;
      }

      /// <summary>
      /// Checks to add versions to change to...
      /// </summary>
      private void CheckChangeRemoveVersion ()
      {
         int itemCount = 0;
         for (int a = 0; a < this.m_tsddVersions.DropDownItems.Count; a++)
         {
            if (this.m_tsddVersions.DropDownItems[a].GetType () == typeof (ToolStripSeparator))
            {
               if (itemCount == 1)
               {
                  ToolStripMenuItem tsmiR = this.m_tsddVersions.DropDownItems[a - 1] as ToolStripMenuItem;
                  if (tsmiR != null)
                  {
                     int tsmiRIndex = tsmiR.DropDownItems.IndexOfKey ("Remove");
                     ToolStripMenuItem tsmiRemoveO = tsmiR.DropDownItems[tsmiRIndex] as ToolStripMenuItem;
                     if (tsmiRemoveO != null) tsmiRemoveO.Enabled = false;
                  }
               }
               break;
            }

            itemCount++;
            ToolStripMenuItem tsmi = this.m_tsddVersions.DropDownItems[a] as ToolStripMenuItem;
            if (tsmi != null)
            {
               int tsmiIndex = tsmi.DropDownItems.IndexOfKey ("Remove");
               ToolStripMenuItem tsmiRemove = tsmi.DropDownItems[tsmiIndex] as ToolStripMenuItem;
               if (tsmiRemove != null) tsmiRemove.Enabled = true;
               tsmiIndex = tsmi.DropDownItems.IndexOfKey ("Change");
               ToolStripMenuItem tsmiChange = tsmi.DropDownItems[tsmiIndex] as ToolStripMenuItem;
               if (tsmiChange != null)
               {
                  tsmiChange.DropDownItems.Clear ();

                  foreach (ToolStripMenuItem tsmiAdd in this.m_TsmiAdd.DropDownItems)
                  {
                     ToolStripMenuItem tsmiNew = new ToolStripMenuItem (tsmiAdd.Text) {Tag = tsmiAdd.Tag};
                     tsmiNew.Click += ChangeVersionClick;
                     tsmiChange.DropDownItems.Add (tsmiNew);
                  }

                  tsmiChange.Enabled = (tsmiChange.DropDownItems.Count > 0);
               }
            }
         }
      }

      /// <summary>
      /// Changes the selected Version...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">Events</param>
      void ChangeVersionClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmiC = sender as ToolStripMenuItem;
         if (tsmiC != null)
         {
            ToolStripMenuItem tsmi = tsmiC.OwnerItem.OwnerItem as ToolStripMenuItem;
            foreach (CjData.IcDbInfo dbi in this.m_Versions)
            {
               if (tsmi != null)
               {
                  if (dbi.Name == tsmi.Text)
                  {
                     dbi.Name = tsmiC.Text;
                     dbi.Path = tsmiC.Tag.ToString ();
                     tsmi.Text = tsmiC.Text;
                     tsmi.Name = tsmiC.Text;
                     tsmi.Tag = tsmiC.Tag;
                     break;
                  }
               }
            }
         }
         this.LoadBookList (true);
      }

      /// <summary>
      /// Adds the selected Version...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">Events</param>
      void AddVersionClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmiO = sender as ToolStripMenuItem;
         if (tsmiO != null) this.AddVersion (tsmiO.Text, tsmiO.Tag.ToString ());
         this.LoadBookList (true);
      }

      /// <summary>
      /// Adds a version to this reader.
      /// </summary>
      /// <param name="version">Name of Version.</param>
      /// <param name="dbPath">Path to version's database.</param>
      public void AddVersion (string version, string dbPath)
      {
         ToolStripMenuItem tsmi = new ToolStripMenuItem (version) {Name = version, Tag = dbPath};

         ToolStripMenuItem tsmiRemove = new ToolStripMenuItem ("Remove Version") {Name = "Remove"};
         tsmiRemove.Click += RemoveVersionClick;
         tsmi.DropDownItems.Add (tsmiRemove);
         ToolStripMenuItem tsmiChange = new ToolStripMenuItem ("Change Version") {Name = "Change"};
         tsmi.DropDownItems.Add (tsmiChange);

         this.m_tsddVersions.DropDownItems.Insert (this.m_tsddVersions.DropDownItems.Count - 2, tsmi);

         this.m_Versions.Add (new CjData.IcDbInfo (dbPath, version));
      }

      /// <summary>
      /// Removes the selected Version...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">Events</param>
      void RemoveVersionClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         if (tsmi != null)
         {
            this.m_tsddVersions.DropDownItems.Remove (tsmi.OwnerItem);
            foreach (CjData.IcDbInfo dbI in this.m_Versions)
            {
               if (dbI.Name.Equals (tsmi.OwnerItem.Text))
               {
                  this.m_Versions.Remove (dbI);
                  break;
               }
            }
         }
         this.LoadBookList (true);
      }

      #endregion

      #region - Load Book List -

      /// <summary>
      /// Loads the list of books in the tree view...
      /// </summary>
      /// <param name="loadPreface">Load the Preface or Not.</param>
      public void LoadBookList (bool loadPreface)
      {
         this.GetBibleAbbrev ();

         if (this.m_Type == Common.TYPE_REFERENCE)
         {
            this.LoadReference ();
            return;
         }


         int mScrollTop = 0;
         int sScrollTop = 0;
         if (this.m_WebMain.Document != null && this.m_WebSplit.Document != null)
         {
            if (this.m_WebMain.Document.Body != null && this.m_WebSplit.Document.Body != null)
            {
               mScrollTop = this.m_WebMain.Document.Body.ScrollTop;
               sScrollTop = this.m_WebSplit.Document.Body.ScrollTop;
            }
         }

         List<CPassage> selPassages = (from n in this.m_List.SelectedNodes where n.Parent != null select new CPassage (n.Parent.Text, n.Text)).ToList ();
         this.m_List.Nodes.Clear ();
         this.m_List.SelectedNodes.Clear ();

         this.m_DbConn.Open ();
         if (this.m_HasSubBooks)
         {
            SQLiteCommand command = this.m_DbConn.CreateCommand ();
            command.CommandText = string.Format ("SELECT Name, BookOrder FROM book_list ORDER BY BookOrder");
            SQLiteDataReader reader = command.ExecuteReader ();
            while (reader.Read ())
            {
               TreeNode n = new TreeNode (reader.GetString (0));
               n.Name = n.Text;

               SQLiteCommand commandChapters = this.m_DbConn.CreateCommand ();
               commandChapters.CommandText =
                  string.Format ("SELECT COUNT(DISTINCT Chapter) AS NumChaps FROM book_text WHERE Book='{0}'", n.Text);
               SQLiteDataReader readerChapters = commandChapters.ExecuteReader ();
               readerChapters.Read ();
               int numChapters = readerChapters.GetInt32 (0);
               //SELECT count(DISTINCT Customer) AS '# of customers' FROM Orders;
               for (int b = 1; b <= numChapters; b++)
               {
                  n.Nodes.Add (b.ToString ());
               }

               this.m_List.Nodes.Add (n);
            }
            reader.Dispose ();
         }
         else
         {
            SQLiteCommand commandChapters = this.m_DbConn.CreateCommand ();
            commandChapters.CommandText = "SELECT DISTINCT Book, COUNT(DISTINCT Chapter) AS NumChaps FROM book_text";
            SQLiteDataReader readerChapters = commandChapters.ExecuteReader ();
            readerChapters.Read ();
            int numChapters = readerChapters.GetInt32 (1);
            //SELECT count(DISTINCT Customer) AS '# of customers' FROM Orders;
            string book = readerChapters.GetString (0);
            for (int b = 1; b <= numChapters; b++)
            {
               TreeNode n = new TreeNode (b.ToString ()) {Tag = book};
               this.m_List.Nodes.Add (n);
            }
         }
         this.m_DbConn.Close ();

         if (this.m_Versions.Count > 1)
         {
            SyncBookList ();
         }
         if (this.m_List.Nodes.Count == 1)
         {
            this.m_List.Nodes[0].Expand ();
         }

         this.m_List.Nodes.Insert (0, Common.PREFACE);
         if (selPassages.Count > 0)
         {
            this.SelectPassages (selPassages);
            if (this.m_WebMain.Document != null && this.m_WebSplit.Document != null)
            {
               if (this.m_WebMain.Document.Body != null && this.m_WebSplit.Document.Body != null)
               {
                  this.m_WebMain.Document.Body.ScrollTop = mScrollTop;
                  this.m_WebSplit.Document.Body.ScrollTop = sScrollTop;
               }
            }
         }
         else
         {
            if (loadPreface)
            {
               List<TreeNode> selNodes = new List<TreeNode> {this.m_List.Nodes [0]};
               this.m_List.SelectedNodes = selNodes;
               this.MListAfterSelect (null, null);
            }
         }
         this.m_Loaded = true;
      }

      /// <summary>
      /// Sychronize book list with all versions...
      /// </summary>
      private void SyncBookList ()
      {
         for (int a = 1; a < this.m_Versions.Count; a++)
         {
            List<string> books = new List <string> ();
            using (SQLiteConnection dbConn = new SQLiteConnection (Common.ConnString (this.m_Versions[a].Path)))
            {
               dbConn.Open ();
               SQLiteCommand command = dbConn.CreateCommand ();
               command.CommandText = "SELECT Name from book_list";
               using (SQLiteDataReader reader = command.ExecuteReader ())
               {
                  while (reader.Read ()) books.Add (reader.GetString (0));
               }
            }

            for (int c = this.m_List.Nodes.Count - 1; c >= 0; c--)
            {
               TreeNode node = this.m_List.Nodes[c];
               if (!books.Contains (node.Text))
               {
                  this.m_List.Nodes.Remove (node);
               }
            }
         }
      }

      #endregion

      #region - Tree Selection -

      /// <summary>
      /// Load next information...
      /// </summary>
      /// <param name="sender">Tree Node</param>
      /// <param name="e">Event</param>
      private void MListAfterSelect (object sender, TreeViewEventArgs e)
      {
         bool newData = false;
         string tabText = "";
         string lastBook = "";
         // Get nodes...
         List<TreeNode> nodes = this.m_List.SelectedNodes;
         StringBuilder sb = GetHeadingHtml ();

         foreach (TreeNode node in nodes)
         {
            bool isChapter = Common.IsNumeric (node.Text);
            if (node.Text == Common.PREFACE)
            {
               sb.Append (this.GetPreface ());
               newData = true;
               lastBook = Common.PREFACE;
               tabText += Common.PREFACE;
            }
            else if (node.Parent != null || isChapter)
            {
               // Create the table...
               string book = (isChapter && node.Parent == null) ? node.Tag.ToString () : node.Parent.Text;
               sb.Append (this.GetTable (book, node.Text));

               newData = true;

               if (lastBook.Length == 0)
               {
                  if (this.m_List.Nodes.Count == 1)
                  {
                     tabText += node.Text;
                  }
                  else
                  {
                     tabText += Parser.GetBook (book, false) + " " + node.Text;
                  }
               }
               else
               {
                  if (lastBook == book)
                  {
                     tabText += "," + node.Text;
                  }
                  else
                  {
                     tabText += ";" + Parser.GetBook (book, false) + " " + node.Text;
                  }
               }
               lastBook = book;
            }
         }

         sb.Append ("</table></div></div></body></html>");

         if (newData)
         {
            // Check to see if the Version's Abbrevation is the same as the Book's...
            if (tabText.Contains (" ") && this.m_Abbrevation.Equals (tabText.Substring (0, tabText.IndexOf (' '))))
               tabText = tabText.Substring (tabText.IndexOf (' ') + 1);
            // If the Tab text is the Same, then we have the same chapters, we can leave and do nothing...
            if (this.TabTitle.Equals (this.m_Abbrevation + " | " + tabText, StringComparison.CurrentCultureIgnoreCase))
               return;

            // Set Tab Text...
            this.TabTitle = this.m_Abbrevation + " | " + tabText;
            // Add History...
            this.AddHistory (tabText);

            this.m_WebMain.HTML = sb.ToString ();

            if (this.m_Passages != null)
            {
               if (this.m_WebMain.Document != null)
               {
                  HtmlElementCollection els = this.m_WebMain.Document.GetElementsByTagName ("tr");
                  for (int z = 0; z < els.Count; z++)
                  {
                     HtmlElement el = els [z];
                     if (!string.IsNullOrEmpty (el.Style) && el.Style.Contains ("BACKGROUND-COLOR: yellow"))
                     {
                        el.ScrollIntoView (true);
                        break;
                     }
                  }
               }
               this.m_Passages = null;
            }

            if (this.m_tsbSplit.Checked)
            {
               this.m_WebSplit.HTML = sb.ToString ();
            }

            this.m_WebMain.Focus ();
         }
      }

      #endregion

      #region -= History =-

      /// <summary>
      /// Updates the History for this reader
      /// </summary>
      /// <param name="tabText">Text Found on Tab.</param>
      private void AddHistory (string tabText)
      {
         // Create the History Item...
         string history = "";
         List<string[]> historyTag = new List<string[]> ();
         if (this.m_Type == Common.TYPE_REFERENCE)
         {
            history = tabText;
         }
         else
         {
            foreach (CjData.IcDbInfo dbi in this.m_Versions)
            {
               history += dbi.Name + ", ";
               string[] hTag = new string[2];
               hTag[0] = dbi.Name;
               hTag[1] = dbi.Path;
               historyTag.Add (hTag);
            }
            history = history.Trim ().TrimEnd (new [] { ',' });
            history += " | " + tabText;
         }

         // Check and see if we have the items in history already...
         if (this._btnNavBack.DropDown.Items.ContainsKey (history))
         {
            int index = this._btnNavBack.DropDown.Items.IndexOfKey (history);
            ToolStripMenuItem tsmiOld = (ToolStripMenuItem)this._btnNavBack.DropDown.Items[index];
            if (tsmiOld.Checked)
               return;

            if (index > 0)
               this._btnNavForward.Enabled = true;

            this.ClearHistoryChecks ();
            tsmiOld.Checked = true;
            return;
         }

         ToolStripMenuItem tsmi = new ToolStripMenuItem (history) {Name = history};
         tsmi.Click += HistoryClick;
         tsmi.Tag = historyTag;

         // If we have more than 30, remove the last one...
         if (this._btnNavBack.DropDown.Items.Count == 30)
         {
            this._btnNavBack.DropDown.Items.RemoveAt (29);
         }
         this._btnNavBack.DropDown.Items.Insert (0, tsmi);
         this._btnNavForward.Enabled = false;
         this.ClearHistoryChecks ();
         tsmi.Checked = true;
      }

      /// <summary>
      /// Navigate Through History...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">EventArgs</param>
      void HistoryClick (object sender, EventArgs e)
      {
         ToolStripMenuItem historyItem = sender as ToolStripMenuItem;
         if (historyItem != null)
         {
            if (historyItem.Checked)
               return;

            this.SelectHistoryItem (historyItem);
         }
      }

      /// <summary>
      /// Selects the given History Item...
      /// </summary>
      /// <param name="historyItem">Item to select.</param>
      private void SelectHistoryItem (ToolStripMenuItem historyItem)
      {
         this.ClearHistoryChecks ();
         historyItem.Checked = true;
         this._btnNavForward.Enabled = (this._btnNavBack.DropDown.Items.IndexOf (historyItem) > 0);

         if (this.m_Type == Common.TYPE_REFERENCE)
         {
            this.SelectRefWords (historyItem.Text.Split (','));
         }
         else if (this.m_Type == Common.TYPE_BIBLE)
         {
            // Check Versions...
            this.CheckHistoryVersions (historyItem);
            string passage = historyItem.Text.Split ('|')[1].Trim ();
            if (passage.Equals (Common.PREFACE))
               this.m_List.SelectedNode = this.m_List.Nodes[0];
            else
               this.SelectPassages (Parser.Parse (passage));
         }
         else
         {
            string chapters = historyItem.Text.Split ('|')[1].Trim ();
            //chapters = chapters.Substring(chapters.IndexOf(" ")).Trim();
            this.SelectChapter (1, chapters.Split (','));
         }
      }

      /// <summary>
      /// Check to see if we need to update the version when we change history...
      /// </summary>
      /// <param name="historyItem">History Item in question.</param>
      private void CheckHistoryVersions (ToolStripMenuItem historyItem)
      {
         List<string[]> versions = (List<string[]>)historyItem.Tag;

         // Check if we need to add versions...
         bool newVersion = versions.Select (version => this.m_Versions.Any (v => v.Path.Equals (version [1]))).Any (found => !found);

         if (!newVersion)
         {
            // Check if we need to remove versions...
            if (this.m_Versions.Select (version => versions.Any (v => v [1].Equals (version.Path))).Any (found => !found))
            {
               newVersion = true;
            }
         }

         if (newVersion)
         {
            // Change the Versions...
            this.m_tsddVersions.DropDownItems.Clear ();
            this.m_Versions.Clear ();
            foreach (string[] version in versions)
            {
               if (this.m_tsddVersions.DropDownItems.Count == 0)
               {
                  this.m_Versions.Add (new CjData.IcDbInfo (version[1], version[0]));
                  this.SetupVersions (version[0], version[1]);
               }
               else
                  this.AddVersion (version[0], version[1]);
            }
            this.LoadBookList (false);
         }
      }

      /// <summary>
      /// Navigate Backward Through History...
      /// </summary>
      /// <param name="sender">ToolStripMenuButton</param>
      /// <param name="e">EventArgs</param>
      void NavHistoryBackClick (object sender, EventArgs e)
      {
         int currIndex = this.GetSelectedHistoryItemIndex ();
         if (currIndex == this._btnNavBack.DropDown.Items.Count - 1)
            return;
         this.SelectHistoryItem ((ToolStripMenuItem)this._btnNavBack.DropDown.Items[currIndex + 1]);
      }

      /// <summary>
      /// Navigate Forward Through History...
      /// </summary>
      /// <param name="sender">ToolStripMenuButton</param>
      /// <param name="e">EventArgs</param>
      private void NavHistoryForwardClick (object sender, EventArgs e)
      {
         int currIndex = this.GetSelectedHistoryItemIndex ();
         if (currIndex > 0)
            this.SelectHistoryItem ((ToolStripMenuItem)this._btnNavBack.DropDown.Items[currIndex - 1]);
      }

      /// <summary>
      /// Gets the Selected History Item...
      /// </summary>
      /// <returns>Index of Selected History Item.</returns>
      private int GetSelectedHistoryItemIndex ()
      {
         int count = 0;
         foreach (ToolStripMenuItem tsmi in this._btnNavBack.DropDown.Items)
         {
            if (tsmi.Checked)
            {
               return count;
            }
            count++;
         }

         return -1;
      }

      /// <summary>
      /// Clears all the Checks on the History Items
      /// </summary>
      private void ClearHistoryChecks ()
      {
         foreach (ToolStripMenuItem tsmi in this._btnNavBack.DropDown.Items)
         {
            tsmi.Checked = false;
         }
      }

      #endregion

      #region -= Get Heading HTML =-

      /// <summary>
      /// Gets the Heading HTML for displaying data...
      /// </summary>
      /// <returns>String Builder with heading html.</returns>
      private StringBuilder GetHeadingHtml ()
      {
         StringBuilder sb = new StringBuilder ();
         sb.Append (this.m_FormMain.GetHtmlHeader ());
         sb.Append ("<div id=\"reader\"><div id=\"readerTitles\"><table width=\"100%\">");
         int w = 100 / this.m_Versions.Count;
         for (int a = 0; a < this.m_Versions.Count; a++)
         {
            sb.Append ("<col width=\"" + w + "%\">");
         }

         sb.Append ("<tr>");

         foreach (CjData.IcDbInfo dbI in this.m_Versions)
         {
            sb.Append ("<th align=\"center\" width=\"" + w + "%\" style=\"filter:progid:DXImageTransform.Microsoft.Gradient(endColorstr='#0060A5', startColorstr='#C0CFE2', gradientType='0');color:white;\">");
            sb.Append (dbI.Name);
            sb.Append ("</th>");
         }

         sb.Append ("</tr></table></div>");
         sb.Append ("<div id=\"innerReader\"><table width=\"100%\">");
         if (this.m_Tsk)
            sb.Append ("<col width=\"25px\">");
         sb.Append ("<col width=\"3%\">");
         for (int a = 0; a < this.m_Versions.Count; a++)
         {
            sb.Append ("<col width=\"" + w + "%\">");
         }
         sb.Append ("<col width=\"3%\">");

         return sb;
      }

      #endregion

      #region - Reference -

      /// <summary>
      /// Loads the Reference Words...
      /// </summary>
      private void LoadReference ()
      {
         StringBuilder sb = this.GetHeadingHtml ();
         sb.Append (this.GetPreface ());
         sb.Append ("</table></div></div></body></html>");
         this.m_WebMain.HTML = this.m_WebSplit.HTML = sb.ToString ();

         this._Working.SetText ("Loading Reference List...");
         this._Working.Visible = true;
         this.m_RefList.Items.Clear ();
         Thread t = new Thread (LoadReferenceThread);
         t.Start ();
      }

      /// <summary>
      /// Loads the Reference Words...
      /// </summary>
      private void LoadReferenceThread ()
      {
         this.m_DbConn.Open ();
         SQLiteCommand command = this.m_DbConn.CreateCommand ();
         command.CommandText = "SELECT Word FROM book_text";
         List<string> words = new List<string> ();
         using (SQLiteDataReader reader = command.ExecuteReader ())
         {
            while (reader.Read ()) words.Add (reader.GetString (0));
         }

         this.Invoke (this.m_AddRef, new object[] { Common.PREFACE });
         foreach (string word in words)
         {
            this.Invoke (this.m_AddRef, new object[] { word });
         }
         this.Invoke (this.m_RefLoaded);
         this.m_DbConn.Close ();
      }

      /// <summary>
      /// Occurs when an Item in the list is selected...
      /// </summary>
      /// <param name="sender">ListItem</param>
      /// <param name="e">Events</param>
      void RefListSelection (object sender, EventArgs e)
      {
         ListItemCollection items = this.m_RefList.SelectedItems;//.SelectedText;
         StringBuilder sb = this.GetHeadingHtml ();

         if (this.m_RefList.SelectedIndex == 0)
         {
            this.TabTitle = this.m_Abbrevation + " | " + Common.PREFACE;
            sb.Append (this.GetPreface ());
            this.AddHistory (Common.PREFACE);
         }
         else
         {
            string tabText = this.m_Abbrevation + " | ";
            this.m_DbConn.Open ();
            foreach (ListItem li in items)
            {
               SQLiteCommand command = this.m_DbConn.CreateCommand ();
               command.CommandText = string.Format ("SELECT * FROM book_text WHERE Word='{0}'", li.Text);
               using (SQLiteDataReader reader = command.ExecuteReader())
               {
                  tabText += li.Text + ",";
                  sb.Append ("<tr><td><h3>" + li.Text + "</h3></td></tr>");
                  while (reader.Read ())
                  {
                     string text = reader.GetString (reader.GetOrdinal ("Text"));
                     string notes = reader.GetString (reader.GetOrdinal ("Notes"));
                     if (!string.IsNullOrEmpty (notes))
                     {
                        sb.Append ("<tr><td>(" + notes + ")</td></tr>");
                     }
                     sb.Append ("<tr><td>");
                     sb.Append (text);
                     sb.Append ("</td></tr>");
                  }
               }
            }
            this.m_DbConn.Close ();
            tabText = tabText.TrimEnd (',');

            if (this.TabTitle.Equals (tabText))
               return;
            this.TabTitle = tabText;
            this.AddHistory (tabText.Split ('|')[1].Trim ());
         }
         sb.Append ("</table></div></div></body></html>");

         this.m_WebMain.HTML = sb.ToString ();
         if (this.m_tsbSplit.Checked)
         {
            this.m_WebSplit.HTML = sb.ToString ();
         }
      }

      /// <summary>
      /// Selectes the given Reference word...
      /// </summary>
      /// <param name="word">Word to Select.</param>
      /// <param name="tryContains">Check if one of the list items contains the word.</param>
      /// <returns>True if word was selected, otherwise false</returns>
      public bool SelectRefWord (string word, bool tryContains)
      {
         foreach (ListItem li in this.m_RefList.Items)
         {
            if (li.Text.Equals (word, StringComparison.CurrentCultureIgnoreCase))
            {
               this.m_RefList.SelectedItem = li;
               return true;
            }
         }
         if (!this.m_Loaded)
         {
            CPassage p = new CPassage (word, "1");
            this.m_Passages = new List<CPassage> {p};
         }
         if (tryContains)
         {
            foreach (ListItem li in this.m_RefList.Items)
            {
               if (li.Text.ToLower ().Contains (word.ToLower ()))
               {
                  this.m_RefList.SelectedItem = li;
                  return true;
               }
            }
         }

         return false;
      }

      /// <summary>
      /// Selectes the given Reference words...
      /// </summary>
      /// <param name="words">Words to Select.</param>
      public void SelectRefWords (string[] words)
      {
         ListItemCollection lic = new ListItemCollection (this.m_RefList);

         foreach (ListItem li in this.m_RefList.Items)
         {
            foreach (string word in words)
            {
               if (li.Text.Equals (word))
               {
                  lic.Add (li);
               }
            }
         }

         this.m_RefList.SelectedItems = lic;
         if (!this.m_Loaded)
         {
            this.m_Passages = new List<CPassage> ();
            foreach (string word in words)
            {
               CPassage p = new CPassage (word, "1");
               this.m_Passages.Add (p);
            }
         }
      }

      /// <summary>
      /// Add the given word to the reference list...
      /// </summary>
      /// <param name="word">Word to add</param>
      private void AddRefWord (string word)
      {
         this.m_RefList.Items.Add (new ListItem (word));
         Application.DoEvents ();
      }

      /// <summary>
      /// Handles some finishing routines for loading Reference...
      /// </summary>
      private void RefLoaded ()
      {
         if (this.m_Passages != null)
         {
            ListItemCollection lic = new ListItemCollection (this.m_RefList);
            foreach (CPassage passage in this.m_Passages)
            {
               foreach (ListItem li in this.m_RefList.Items)
               {
                  if (passage.Book.Equals (li.Text))
                  {
                     lic.Add (li);
                     break;
                  }
               }
            }
            this.m_RefList.SelectedItems = lic;
            this.m_Passages.Clear ();
            this.m_Passages = null;
         }
         else
         {
            this.m_RefList.Items[0].Selected = true;
            this.m_RefList.Refresh ();
         }
         this._Working.Visible = false;
      }

      #endregion

      #region - Get Table (string) -

      /// <summary>
      /// Create an HTML Table with the given results
      /// </summary>
      /// <param name="book">Book to get Table for</param>
      /// <param name="chapter">Chapter to get table for</param>
      /// <returns>html table string.</returns>
      private string GetTable (string book, string chapter)
      {
         List<SQLiteDataReader> dbResults = new List<SQLiteDataReader> ();

         // Get results for each version...
         foreach (CjData.IcDbInfo dbI in this.m_Versions)
         {
            SQLiteConnection dbConn = new SQLiteConnection (Common.ConnString (dbI.Path));
            dbConn.Open ();
            SQLiteCommand command = dbConn.CreateCommand ();
            command.CommandText = string.Format ("SELECT * FROM book_text WHERE Book='{0}' AND Chapter={1} ORDER BY Verse", book, chapter);
            dbResults.Add (command.ExecuteReader());
         }

         // Build Results...
         if (dbResults.Count > 0)
         {
            // Build Table...
            StringBuilder sb = new StringBuilder ();
            sb.Append ("<tr>");
            int tds = (this.m_Tsk) ? 3 : 2;
            sb.Append ("<th colspan=\"" + Convert.ToString (tds + dbResults.Count) + "\" align=\"center\" style=\"filter:progid:DXImageTransform.Microsoft.Gradient(endColorstr='#D8D8D8', startColorstr='#FFFFFF', gradientType='0');\">");
            sb.Append (book + ((book.IndexOf ("Psalm") == 0) ? " " : " Chapter ") + chapter);
            sb.Append ("</th>");
            sb.Append ("</tr>");
            int verse = 1;

            // Loop throught results...
            int dbCount = dbResults.Count;
            while (dbResults[0].Read ())
            {
               for (int a = 0; a < dbCount; a++)
               {
                  if (a != 0) dbResults[a].Read ();
                  string header = dbResults[a].GetString (dbResults[a].GetOrdinal ("Header"));
                  AddHeader (sb, header, a);
               }

               // Chapter:Verse Label...
               bool temp = false;
               if (this.m_Passages != null)
               {
                  foreach (CPassage pass in this.m_Passages)
                  {
                     if (pass.Book == book && pass.Verse != null)
                     {
                        if (pass.Chapter == chapter && pass.Verse == verse.ToString ())
                        {
                           temp = true;
                        }
                     }
                  }
               }

               sb.Append ("<tr passage=\"" + book + "|" + chapter + "|" + verse + "\"");
               sb.Append ("onMouseOver=\"this.className='highliteRow'\" onMouseOut=\"this.className='normalRow'\"");
               if (temp)
                  sb.Append (" style=\"background-color:yellow;\"");

               sb.Append (">");

               if (this.m_Tsk)
               {
                  sb.Append ("<td valign=\"top\" align=\"right\">");
                  sb.Append ("<div title=\"Treasury of Scripture Knowledge\" style=\"font-size:70%;cursor:hand;border:0px;\" destina=\"tsk|" +
                      book + "|" + chapter + "|" + verse + "\">TSK</div>");
                  sb.Append ("</td>");
               }

               sb.Append ("<td class=\"passage\" valign=\"top\" align=\"right\">");
               sb.Append (chapter + ":" + verse);
               sb.Append ("</td>");

               // Add Text...
               for (int a = 0; a < dbCount; a++)
               {
                  string text = dbResults[a].GetString (dbResults[a].GetOrdinal ("Text"));
                  sb.Append ("<td align=\"left\" valign=\"top\" version=\"" + a + "\">");
                  sb.Append (text);
                  sb.Append ("</td>");
               }

               // Chapter:Verse Label...
               sb.Append ("<td class=\"passage\" valign=\"top\" align=\"left\">");
               sb.Append (chapter + ":" + verse);
               sb.Append ("</td>");

               sb.Append ("</tr>");

               if (this.m_Tsk)
               {
                  sb.Append ("<tr style=\"display:none\"><td></td><td></td><td colspan=\"" + Convert.ToString (dbResults.Count) +
                      "\" align=\"center\" version=\"0\"><div id=\"tsk|" + book + "|" + chapter + "|" + verse +
                      "\"></div></td><td></td></tr>");
               }

               sb.Append ("<tr style=\"display:none\"><td></td><td></td><td colspan=\"" + Convert.ToString (dbResults.Count) +
                   "\" align=\"center\" version=\"0\"><div id=\"note|" + book + "|" + chapter + "|" + verse + "\">");
               sb.Append ("</div></td><td></td></tr>");

               // Check for footer...
               for (int a = 0; a < dbCount; a++)
               {
                  string footer = dbResults[a].GetString (dbResults[a].GetOrdinal ("Footer"));
                  AddFooter (sb, footer, a);
               }
               verse++;
            }

            return sb.ToString ();
         }
         return "";
      }

      private void AddHeader (StringBuilder sb, string header, int version)
      {
         if (!string.IsNullOrEmpty (header))
         {
            sb.Append ("<tr><td>&nbsp;</td>");
            if (this.m_Tsk)
               sb.Append ("<td>&nbsp;</td>");
            sb.Append ("<td align=\"left\" version=\"" + version + "\">");
            sb.Append ("<blockquote><small>" + header + "</small></blockquote>");
            sb.Append ("</td>");
            sb.Append ("<td>&nbsp;</td></tr>");
         }
      }

      private void AddFooter (StringBuilder sb, string footer, int version)
      {
         if (!string.IsNullOrEmpty (footer))
         {
            sb.Append ("<tr><td>&nbsp;</td>");
            if (this.m_Tsk)
               sb.Append ("<td>&nbsp;</td>");
            sb.Append ("<td align=\"center\" version=\"" + version + "\">");
            sb.Append ("<small>" + footer + "</small><br/>");
            sb.Append ("</td>");
            sb.Append ("<td>&nbsp;</td></tr>");
         }
      }

      #endregion

      #region - Show/Hide Book List -

      /// <summary>
      /// Shows or hides the book list
      /// </summary>
      /// <param name="sender">Button</param>
      /// <param name="e">Events</param>
      private void MTsbHidBookListClick (object sender, EventArgs e)
      {
         if (this.m_tsbHidBookList.Text == "Hide List")
         {
            this.splitContainer1.Panel1Collapsed = true;
            this.m_tsbHidBookList.Text = "Show List";
         }
         else
         {
            this.splitContainer1.Panel1Collapsed = false;
            this.m_tsbHidBookList.Text = "Hide List";
         }
      }

      #endregion

      #region - Find Next -

      /// <summary>
      /// Finds the next occurance of the requested string...
      /// </summary>
      /// <param name="sender">Button</param>
      /// <param name="e">Event</param>
      private void MTsbFindClick (object sender, EventArgs e)
      {
         if (this.m_txtFind.Text.Trim () != string.Empty)
         {
            this.m_WebMain.FindNext (this.m_txtFind.Text);
         }
      }

      /// <summary>
      /// Occurs when a key stroke happens in the find text...
      /// </summary>
      /// <param name="sender">Find TextBox</param>
      /// <param name="e">Events</param>
      void FindKeyDown (object sender, KeyEventArgs e)
      {
         if (e.KeyCode == Keys.Enter)
            this.MTsbFindClick (sender, null);
      }

      #endregion

      #region - Split View -

      /// <summary>
      /// Shows or Hides the Split view...
      /// </summary>
      /// <param name="sender">Button</param>
      /// <param name="e">Event</param>
      private void MTsbSplitClick (object sender, EventArgs e)
      {
         this.m_SplitRead.Panel2Collapsed = !this.m_tsbSplit.Checked;
         if (this.m_tsbSplit.Checked)
         {
            this.m_WebSplit.HTML = this.m_WebMain.HTML;
         }
      }

      #endregion

      #region - Select Chapter -

      /// <summary>
      /// Selects the Next Chapter...
      /// </summary>
      /// <param name="sender">ToolStripButton</param>
      /// <param name="e">Events</param>
      private void BtnNextChapterClick (object sender, EventArgs e)
      {
         if (this.m_Type == Common.TYPE_REFERENCE)
         {
            if (this.m_RefList.Items.Count > 0)
            {
               int selIndex = this.m_RefList.SelectedIndex + 1;
               this.m_RefList.SelectedIndex = selIndex >= this.m_RefList.Items.Count ? 0 : selIndex;
            }
         }
         else
         {
            if (this.m_List.SelectedNode == null)
            {
               this.SelectFirstChapter ();
            }
            else
            {
               if (this.m_List.SelectedNode.Parent == null)
               {
                  this.m_List.SelectedNode = this.m_List.SelectedNode.FirstNode;
               }
               else
               {
                  if (this.m_List.SelectedNode.NextNode == null)
                  {
                     if (this.m_List.SelectedNode.Parent.NextNode != null && this.m_List.SelectedNode.Parent.NextNode.Nodes.Count > 0)
                     {
                        this.m_List.SelectedNode = this.m_List.SelectedNode.Parent.NextNode.FirstNode;
                     }
                     else
                     {
                        this.SelectFirstChapter ();
                     }
                  }
                  else
                     this.m_List.SelectedNode = this.m_List.SelectedNode.NextNode;
               }
            }
         }
      }

      /// <summary>
      /// Selects the Previous Chapter...
      /// </summary>
      /// <param name="sender">ToolStripButton</param>
      /// <param name="e">Events</param>
      private void BtnPreviousChapterClick (object sender, EventArgs e)
      {
         if (this.m_Type == Common.TYPE_REFERENCE)
         {
            if (this.m_RefList.Items.Count > 0)
            {
               int selIndex = this.m_RefList.SelectedIndex - 1;
               if (selIndex < 0)
               {
                  this.m_RefList.SelectedIndex = this.m_RefList.Items.Count - 1;
               }
               else
               {
                  this.m_RefList.SelectedIndex = selIndex;
               }
            }
         }
         else
         {
            if (this.m_List.SelectedNode == null)
            {
               this.SelectFirstChapter ();
            }
            else
            {
               if (this.m_List.SelectedNode.Parent == null)
               {
                  this.m_List.SelectedNode = this.m_List.SelectedNode.FirstNode;
               }
               else
               {
                  if (this.m_List.SelectedNode.PrevNode == null)
                  {
                     if (this.m_List.SelectedNode.Parent.PrevNode != null && this.m_List.SelectedNode.Parent.PrevNode.Nodes.Count > 0)
                     {
                        this.m_List.SelectedNode = this.m_List.SelectedNode.Parent.PrevNode.LastNode;
                     }
                     else
                     {
                        this.SelectLastChapter ();
                     }
                  }
                  else
                     this.m_List.SelectedNode = this.m_List.SelectedNode.PrevNode;
               }
            }
         }
      }

      /// <summary>
      /// Selects the very first Chapter in the list...
      /// </summary>
      private void SelectFirstChapter ()
      {
         foreach (TreeNode node in this.m_List.Nodes)
         {
            if (node.Nodes.Count > 0)
            {
               this.m_List.SelectedNode = node.Nodes[0];
               break;
            }
         }
      }

      /// <summary>
      /// Selectes the very last Chapter in the list...
      /// </summary>
      private void SelectLastChapter ()
      {
         if (this.m_List.Nodes.Count > 0)
            if (this.m_List.Nodes[this.m_List.Nodes.Count - 1].Nodes.Count > 0)
               this.m_List.SelectedNode = this.m_List.Nodes[this.m_List.Nodes.Count - 1].LastNode;
      }

      /// <summary>
      /// Selectes the given chapter in the given node...
      /// </summary>
      /// <param name="node">Node that contains chapter.</param>
      /// <param name="chaps">Chapter to select.</param>
      public void SelectChapter (int node, string[] chaps)
      {
         if (this.m_List.Nodes.Count > node && node >= 0)
         {
            this.m_List.ClearSelection ();
            List<TreeNode> selNodes = chaps.Select (chap => chap.Equals (Common.PREFACE) ? this.m_List.Nodes [0] : this.m_List.Nodes [node].Nodes [Convert.ToInt32 (chap) - 1]).ToList ();
            this.m_List.SelectedNodes = selNodes;
            this.MListAfterSelect (null, null);
         }
      }

      #endregion

      #region - Quick Jump -

      /// <summary>
      /// Occurs when a key stroke happens in the Quick Jump text...
      /// </summary>
      /// <param name="sender">Quick Jump TextBox</param>
      /// <param name="e">Events</param>
      void QuickJumpKeyDown (object sender, KeyEventArgs e)
      {
         if (e.KeyCode == Keys.Enter)
            this.BtnQjGoClick (sender, null);
      }

      /// <summary>
      /// Parses the List of Passages in the Quick Jump TextBox...
      /// </summary>
      /// <param name="sender">ToolStripButton</param>
      /// <param name="e">Events</param>
      private void BtnQjGoClick (object sender, EventArgs e)
      {
         List<CPassage> passages = Parser.Parse (txtQJ.Text);
         SelectPassages (passages);
      }

      /// <summary>
      /// Selects the List of Given Passages...
      /// </summary>
      /// <param name="passages">List of Passages to Select.</param>
      public void SelectPassages (List<CPassage> passages)
      {
         this.CheckVersions (passages);
         this.m_List.ClearSelection ();

         List<TreeNode> selNodes = new List<TreeNode> ();
         foreach (TreeNode root in this.m_List.Nodes)
         {
            foreach (CPassage passage in passages)
            {
               if (!this.m_HasSubBooks)
               {
                  if (root.Text.Equals (passage.Chapter))
                  {
                     if (!selNodes.Contains (root))
                     {
                        selNodes.Add (root);
                     }
                  }
               }
               else if (root.Text.Equals (passage.Book))
               {
                  foreach (TreeNode node in root.Nodes)
                  {
                     if (node.Text.Equals (passage.Chapter))
                     {
                        root.Expand ();
                        if (!selNodes.Contains (node))
                        {
                           selNodes.Add (node);
                        }
                     }
                  }
               }
            }
         }

         this.m_Passages = passages;
         if (selNodes.Count > 0)
         {
            this.m_List.GroupAdd = true;
            this.m_List.SelectedNodes = selNodes;
            this.m_List.SelectedNode = selNodes[0];
            //this.m_List_AfterSelect(null, null);
         }
      }

      /// <summary>
      /// Checks to see if we have all the versions needed...
      /// </summary>
      /// <param name="passages">List of passages with versions.</param>
      private void CheckVersions (IEnumerable <CPassage> passages)
      {
         int addVersion = 0;
         List<string> versions = (from passage in passages where !string.IsNullOrEmpty (passage.Version) select passage.Version).ToList ();
         if (versions.Count > 0)
         {
            foreach (string version in versions)
            {
               string version1 = version;
               bool hasVersion = this.m_Versions.Any (dbi => dbi.Name.Equals (version1));
               if (!hasVersion)
               {
                  this.AddVersion (version, this.m_FormMain.GetDbPath (version));
                  addVersion++;
               }
            }
         }

         if (addVersion > 0)
            this.LoadBookList (true);
      }

      #endregion

      #region - Random Chapter -

      private void GenerateRandomChapter (object sender, EventArgs e)
      {
         try
         {
            Random rand = new Random (DateTime.Now.Millisecond);
            // Get Book...
            TreeNode book = this.m_List.Nodes[rand.Next (this.m_List.Nodes.Count)];

            TreeNode chap = book.Nodes[rand.Next (book.Nodes.Count)];
            this.m_List.SelectedNode = chap;
         }
         catch (Exception ex)
         {
            Console.WriteLine (ex.Message);
            this.GenerateRandomChapter (sender, e);
         }
      }

      #endregion

      #region - MISC -

      /// <summary>
      /// Gets the Current Book...
      /// </summary>
      public string Book
      {
         get
         {
            string book = "";
            if (this.m_Type != Common.TYPE_REFERENCE)
            {
               if (this.m_List.SelectedNode.Parent == null)
               {
                  if (this.m_List.SelectedNode.Text != Common.PREFACE)
                  {
                     book = this.m_List.SelectedNode.Text;
                  }
               }
               else
               {
                  book = this.m_List.SelectedNode.Parent.Text;
               }
            }
            return book;
         }
      }

      /// <summary>
      /// Gets the first webber that has a selection...
      /// </summary>
      /// <returns>Webber with Selection</returns>
      private Webber GetWebber ()
      {
         if (!string.IsNullOrEmpty (this.m_WebMain.Selection))
            return this.m_WebMain;

         if (this.m_tsbSplit.Checked)
         {
            if (!string.IsNullOrEmpty (this.m_WebSplit.Selection))
               return this.m_WebSplit;
         }

         return null;
      }

      /// <summary>
      /// Gets the Webber associated with the context menu item...
      /// </summary>
      /// <param name="tsmi">ToolStripMenuItem in context menu...</param>
      /// <returns>Webber</returns>
      private Webber GetWebber (ToolStripMenuItem tsmi)
      {
         ContextMenuStrip ctx = tsmi.Owner as ContextMenuStrip;
         if (ctx != null)
         {
            if (ctx.SourceControl.Name.Equals ("m_WebSplit"))
               return this.m_WebSplit;
            return this.m_WebMain;
         }
         return null;
      }

      /// <summary>
      /// Gets the Page Info...
      /// </summary>
      /// <returns>Tabber Page Info.</returns>
      public override string GetPageInfo ()
      {
         return this.m_Versions.Aggregate ("", (current, dbi) => current + (dbi.Name + "|" + dbi.Path + "|"));
      }

      /// <summary>
      /// Gets the Type of Reader...
      /// </summary>
      public string ReaderType
      {
         get { return this.m_Type; }
      }

      /// <summary>
      /// Get the name of the given version...
      /// </summary>
      /// <param name="version">Version Index.</param>
      /// <returns>Version Name.</returns>
      public string GetVersion (int version)
      {
         if (version >= 0 && version < this.m_Versions.Count)
            return this.m_Versions[version].Name;
         if (version == -1 && this.m_Versions.Count == 1 && this.m_Type != Common.TYPE_REFERENCE)
            return this.m_Versions[0].Name;
         return "";
      }

      /// <summary>
      /// Gets the Path of the given version
      /// </summary>
      /// <param name="version">Version Index.</param>
      /// <returns>Version Path.</returns>
      public string GetVersionPath (int version)
      {
         if (version >= 0 && version < this.m_Versions.Count)
            return this.m_Versions[version].Path;
         if (version == -1 && this.m_Versions.Count == 1 && this.m_Type != Common.TYPE_REFERENCE)
            return this.m_Versions[0].Path;
         return "";
      }

      /// <summary>
      /// Gets the TabberPage associated with the host...
      /// </summary>
      /// <returns>TabberPage</returns>
      public Tabber.TabberPage GetTabPage ()
      {
         return this;
      }

      /// <summary>
      /// A Method to update the Font...
      /// </summary>
      public void UpdateText ()
      {
         this.MListAfterSelect (null, null);
      }

      #endregion

      #region - Context Menu -

      /// <summary>
      /// Gets the Context Menu for this control.
      /// </summary>
      /// <returns>Context Menu for this control.</returns>
      public ContextMenuStrip GetContextMenu ()
      {
         // Create a new Context Menu...
         ContextMenuStrip ctx = new ContextMenuStrip ();
         ctx.RenderMode = ToolStripRenderMode.System;
         ctx.Opening += CtxOpening;

         // Copy...
         ToolStripMenuItem tsmiCopy = new ToolStripMenuItem ("Copy");
         tsmiCopy.Click += CopyClick;
         tsmiCopy.Name = "copy";
         tsmiCopy.Image = this.m_FormMain.GetInternalImage ("CopyHS");
         // Copy Verse...
         ToolStripMenuItem tsmiCopyV = new ToolStripMenuItem ("Copy Verse");
         tsmiCopyV.Click += CopyVClick;
         tsmiCopyV.Image = this.m_FormMain.GetInternalImage ("_goto");
         tsmiCopyV.Name = "vcopy";
         if (this.m_Type == Common.TYPE_REFERENCE)
            tsmiCopyV.Enabled = false;
         // Search...
         ToolStripMenuItem tsmiSearch = new ToolStripMenuItem ("Search");
         tsmiSearch.Click += SearchClick;
         tsmiSearch.Name = "search";
         tsmiSearch.Image = this.m_FormMain.GetInternalImage ("searchmag");
         // Define...
         ToolStripMenuItem tsmiDefine = new ToolStripMenuItem ("Lookup Definitions");
         tsmiDefine.Click += DefineClick;
         tsmiDefine.Name = "define";
         // BookMark...
         ToolStripMenuItem tsmiBookMark = new ToolStripMenuItem ("Book Mark");
         tsmiBookMark.Click += BookMarkClick;
         tsmiBookMark.Image = this.m_FormMain.GetInternalImage ("bible");
         tsmiBookMark.Name = "bookmark";
         // Verse Notes...
         ToolStripMenuItem tsmiNotes = new ToolStripMenuItem ("Add/Edit Verse Notes");
         tsmiNotes.Click += NoteClick;
         tsmiNotes.Image = this.m_FormMain.GetInternalImage ("NoteHS");
         tsmiNotes.Name = "note";

         ctx.Items.Add (tsmiCopy);
         ctx.Items.Add (new ToolStripSeparator ());
         ctx.Items.Add (tsmiCopyV);
         ctx.Items.Add (tsmiBookMark);
         ctx.Items.Add (tsmiNotes);
         ctx.Items.Add (new ToolStripSeparator ());
         ctx.Items.Add (tsmiSearch);
         ctx.Items.Add (tsmiDefine);

         return ctx;
      }

      /// <summary>
      /// Activates the Copy Command...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">EventArgs</param>
      void CopyClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         this.GetWebber (tsmi).Copy ();
      }

      /// <summary>
      /// Copies the given verse...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">EventArgs</param>
      static void CopyVClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         if (tsmi != null) Clipboard.SetText (tsmi.Tag.ToString ());
      }

      /// <summary>
      /// Adds a book mark...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">EventArgs</param>
      void BookMarkClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         if (tsmi != null) this.m_FormMain.AddBookMark (tsmi.Tag.ToString ());
      }

      /// <summary>
      /// Add/Edit Verse Notes...
      /// </summary>
      /// <param name="sender">ToolStripMenuItem</param>
      /// <param name="e">EventArgs</param>
      void NoteClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         Webber web = this.GetWebber (tsmi);
         //HtmlElement elTD = this.GetTDElement(web);
         //if (elTD == null) return;
         HtmlElement elTr = Common.GetTrElement (web);//web.GetParentElement(elTD, "TR");

         if (elTr != null)
         {
            string dest = "";
            if (elTr.FirstChild != null)
            {
               int index;
               if ((index = elTr.FirstChild.InnerHtml.IndexOf ("destina")) != -1)
                  dest = elTr.FirstChild.InnerHtml.Substring (index + 9, elTr.FirstChild.InnerHtml.IndexOf (">") - 10 - index);

               if (!string.IsNullOrEmpty (dest))
               {
                  dest = dest.Replace ("tsk", "note");
                  if (web.Document != null)
                  {
                     HtmlElement destEl = web.Document.GetElementById (dest);
                     if (destEl != null)
                     {
                        if (destEl.Parent != null)
                        {
                           if (destEl.Parent.Parent != null)
                           {
                              if (destEl.Parent.Parent.Style.Equals ("DISPLAY: block", StringComparison.CurrentCultureIgnoreCase))
                              {
                                 if (!string.IsNullOrEmpty (destEl.InnerHtml))
                                 {
                                    if (!destEl.InnerHtml.Equals ("<TEXTAREA style=\"WIDTH: 100%\" name=notes rows=5 wrap=hard></TEXTAREA><BUTTON align=\"right\">Save</BUTTON>"))
                                       if (MessageBox.Show (this.m_FormMain, "You have notes that have not been saved, are you sure you want to continue?", "Jonathan",
                                                            MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                                          return;
                                 }
                                 destEl.InnerHtml = "";
                                 destEl.Parent.Parent.Style = "DISPLAY: none";
                                 return;
                              }
                              destEl.Parent.Parent.Style = "DISPLAY: block";
                              if (destEl.Parent.Parent.FirstChild != null)
                              {
                                 destEl.Parent.Parent.FirstChild.Style = "BACKGROUND: #D8D8D8";
                                 destEl.Parent.Parent.FirstChild.InnerHtml = "<span style=\"writing-mode: tb-rl;filter: flipv fliph;font-weight:bold;\">Notes</span>";
                              }
                           }
                        }
                        destEl.InnerHtml = "<TEXTAREA name=\"notes\" rows=5 WRAP=HARD style=\"width:100%;\">" + destEl.InnerHtml + "</TEXTAREA><button align=\"right\">Save</button>";
                     }
                  }
               }
            }
         }
      }

      /// <summary>
      /// Occurs when the Search Context menu item is clicked.
      /// </summary>
      /// <param name="sender">Search Context menu item.</param>
      /// <param name="e">Event Arguments.</param>
      void SearchClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         Webber web = this.GetWebber (tsmi);
         //HtmlElement elTD = web.MouseClickElement;
         string text = web.Selection;

         if (!string.IsNullOrEmpty (text))
         {
            // Get Cell (TD)...
            HtmlElement elTd = Common.GetTdElement (web);// this.GetTDElement(web);
            if (elTd == null) return;

            // Get the Version...
            int index;
            string version = "";
            if ((index = elTd.OuterHtml.IndexOf ("version")) != -1)
            {
               version = elTd.OuterHtml.Substring (index + 9, elTd.OuterHtml.IndexOf (">") - 10 - index);
               version = this.GetVersion (Convert.ToInt32 (version));
            }

            // Search...
            this.m_FormMain.Search (version, text, this);
         }
      }

      /// <summary>
      /// Occurs when the Define Context menu item is clicked.
      /// </summary>
      /// <param name="sender">Define Context menu item.</param>
      /// <param name="e">Event Arguments.</param>
      void DefineClick (object sender, EventArgs e)
      {
         ToolStripMenuItem tsmi = sender as ToolStripMenuItem;
         Webber web = this.GetWebber (tsmi);
         string text = web.Selection;

         if (!string.IsNullOrEmpty (text))
         {
            // Search...
            this.m_FormMain.Search (text, this, Common.TYPE_REFERENCE);
         }
      }

      /// <summary>
      /// Occurs when the Context Menu is opening.
      /// </summary>
      /// <param name="sender">Context Menu Strip of Control.</param>
      /// <param name="e">Cancel Event Arguments.</param>
      void CtxOpening (object sender, CancelEventArgs e)
      {
         ContextMenuStrip ctx = sender as ContextMenuStrip;
         if (ctx != null)
         {
            if (ctx.Items.Count <= 0)
               return;

            Webber web = this.GetWebber ((ToolStripMenuItem) ctx.Items [0]);
            ctx.Items ["vcopy"].Enabled = false;
            ctx.Items ["bookmark"].Enabled = false;
            ctx.Items ["note"].Enabled = false;
            ctx.Items ["vcopy"].Text = "Cannot Copy Verse";
            ctx.Items ["bookmark"].Text = "Nothing to Book Mark";
            ctx.Items ["note"].Text = "Cannot add a Note";

            if (string.IsNullOrEmpty (web.Selection))
            {
               ctx.Items ["copy"].Enabled = false;
               ctx.Items ["search"].Enabled = false;
               ctx.Items ["define"].Enabled = false;
               ctx.Items ["define"].Text = "Nothing to Lookup";
               ctx.Items ["search"].Text = "Nothing to Search for";
            }
            else
            {
               ctx.Items ["copy"].Enabled = true;
               ctx.Items ["search"].Enabled = true;
               ctx.Items ["define"].Enabled = true;
               ctx.Items ["define"].Text = "Lookup Definitions for " + web.Selection.Split (' ') [0] + "...";
               ctx.Items ["search"].Text = "Search for " + web.Selection.Split (' ') [0] + "...";
            }

            // Get Cell (TD)...
            HtmlElement elTd = Common.GetTdElement (web);
            if (elTd == null) return;

            // Get the Row (TR)...
            HtmlElement elTr = web.GetParentElement (elTd.Parent, "TR");
            if (elTr == null) return;

            // Lets Copy...
            int index;
            if ((index = elTr.OuterHtml.IndexOf ("passage")) != -1)
            {
               string passage = elTr.OuterHtml.Substring (index + 9, elTr.OuterHtml.IndexOf (">") - 10 - index);
               string[] parsedPassage = passage.Split ('|');

               // Copy Verse...
               ctx.Items ["vcopy"].Text = "Copy " + parsedPassage [0] + " " + parsedPassage [1] + ":" +
                                          parsedPassage [2];
               ctx.Items ["vcopy"].Enabled = true;
               ctx.Items ["vcopy"].Tag = parsedPassage [0] + " " + parsedPassage [1] + ":" + parsedPassage [2] + " - " +
                                         elTd.InnerText;

               // Book Mark...
               ctx.Items ["bookmark"].Text = "Book Mark " + parsedPassage [0] + " " + parsedPassage [1] + ":" +
                                             parsedPassage [2];
               ctx.Items ["bookmark"].Enabled = true;
               ctx.Items ["note"].Text = "Add/Edit Notes for " + parsedPassage [0] + " " + parsedPassage [1] + ":" +
                                         parsedPassage [2];
               ctx.Items ["note"].Enabled = true;

               if ((index = elTd.OuterHtml.IndexOf ("version")) != -1)
               {
                  string version = elTd.OuterHtml.Substring (index + 9, elTd.OuterHtml.IndexOf (">") - 10 - index);
                  version = this.GetVersion (Convert.ToInt32 (version));
                  ctx.Items ["bookmark"].Tag = version + "|" + passage;
                  ctx.Items ["bookmark"].Enabled = true;
               }
            }
         }
      }

      #endregion

      #region -= Formatting =-

      /// <summary>
      /// Italisize the Selected Font...
      /// </summary>
      /// <param name="sender">ToolStripButton</param>
      /// <param name="e">EventArgs</param>
      void BtnItalicClick (object sender, EventArgs e)
      {
         Webber web = this.GetWebber ();
         if (web != null)
         {
            if (web.Document != null) web.Document.ExecCommand ("Italic", false, null);
            this.GetNewVerses (web);
         }
      }

      /// <summary>
      /// Bold the Selected Font...
      /// </summary>
      /// <param name="sender">ToolStripButton</param>
      /// <param name="e">EventArgs</param>
      void BtnBoldClick (object sender, EventArgs e)
      {
         Webber web = this.GetWebber ();
         if (web != null)
         {
            if (web.Document != null) web.Document.ExecCommand ("Bold", false, null);
            this.GetNewVerses (web);
         }
      }

      /// <summary>
      /// Underline the Selected Font...
      /// </summary>
      /// <param name="sender">ToolStripButton</param>
      /// <param name="e">EventArgs</param>
      void BtnUnderlineClick (object sender, EventArgs e)
      {
         Webber web = this.GetWebber ();
         if (web != null)
         {
            if (web.Document != null) web.Document.ExecCommand ("Underline", false, null);
            this.GetNewVerses (web);
         }
      }

      /// <summary>
      /// Change the Selected Text's Color...
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      void ForeColorPickerSelectedColorChanged (object sender, EventArgs e)
      {
         Webber web = this.GetWebber ();
         if (web != null)
         {
            ColorPicker.OfficeColorPicker colorPicker = ((ColorPicker.ToolStripColorDropDown)this._ForeColorPicker.DropDown).ColorPicker;
            if (colorPicker != null)
            {
               if (web.Document != null)
                  web.Document.ExecCommand ("ForeColor", false, ColorTranslator.ToHtml (colorPicker.Color));
               this.GetNewVerses (web);
            }
         }
      }

      /// <summary>
      /// Change the Selected Text's BackColor...
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      void BackColorPickerSelectedColorChanged (object sender, EventArgs e)
      {
         Webber web = this.GetWebber ();
         if (web != null)
         {
            ColorPicker.OfficeColorPicker colorPicker = ((ColorPicker.ToolStripColorDropDown)this._BackColorPicker.DropDown).ColorPicker;
            if (colorPicker != null)
            {
               if (web.Document != null)
                  web.Document.ExecCommand ("BackColor", false, ColorTranslator.ToHtml (colorPicker.Color));
               this.GetNewVerses (web);
            }
         }
      }

      /// <summary>
      /// Gets the New Verses in the bibles..
      /// </summary>
      /// <param name="web">Webber with update</param>
      private void GetNewVerses (Webber web)
      {
         if (this.m_Type == Common.TYPE_REFERENCE)
         {
            this.GetNewReference (web);
            return;
         }

         // Return if the Preface is seleted...
         if (this.m_List.SelectedNodes.Contains (this.m_List.Nodes[0]))
            return;

         web.ClearSelection ();
         string txt = web.innerHTML;
         List<string[]> verses = new List<string[]> ();
         if (!string.IsNullOrEmpty (txt))
         {
            txt = txt.Replace ("\r\n", "");
            string[] tags = txt.Split (new [] { "<TR", "<TD" }, StringSplitOptions.RemoveEmptyEntries);
            string[] verse = new string[3];
            foreach (string tag in tags)
            {
               if (tag.Contains ("passage=\""))
               {
                  int index = tag.IndexOf ("passage=");
                  verse[0] = tag.Substring (index + 9, tag.IndexOf (">") - 10 - index);
               }
               else if (tag.Contains ("vAlign=top align=left version="))
               {
                  // Version...
                  int index = tag.IndexOf ("version=");
                  verse[2] = tag.Substring (index + 9, tag.IndexOf (">") - 10 - index);
                  verse[2] = this.m_Versions[Convert.ToInt32 (verse[2])].Path;

                  // Text...
                  int start = tag.IndexOf ('>') + 1;
                  int end = tag.LastIndexOf ('<');
                  verse[1] = tag.Substring (start, end - start);

                  // Passage
                  if (string.IsNullOrEmpty (verse[0]))
                  {
                     verse[0] = verses[verses.Count - 1][0];
                  }

                  verses.Add (verse);
                  verse = new string[3];
                  // Copy the last passage...
               }
            }
         }

         // Remove the verses that did not change...
         // If we undo the look for (i.e. change from bold to not bold), then we will remove all verses... Hmmmm....
         /*for (int a = verses.Count - 1; a >= 0; a--)
         {
             if (!verses[a][1].Contains(lookFor))
             {
                 verses.Remove(verses[a]);
             }
         }*/

         // Sort and return...
         verses.Sort (new NewVerseListComparer ());

         Thread t = new Thread (this.UpdateBibleTexts);
         t.Start (verses);
      }

      /// <summary>
      /// Gets the New Reference Text..
      /// </summary>
      /// <param name="web">Webber with update</param>
      private void GetNewReference (Webber web)
      {
         if (this.m_RefList.SelectedItems.Count > 0)
         {
            // Do not Do Preface...
            if (this.m_RefList.SelectedItems[0] == this.m_RefList.Items[0])
               return;

            string refTxt = web.innerHTML;
            if (!string.IsNullOrEmpty (refTxt))
            {
               List<string[]> refList = new List<string[]> ();
               string[] lines = refTxt.Split (new [] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
               bool nextTd = false;
               string[] refItem = new string[3];
               refItem[2] = this.m_Versions[0].Path;
               foreach (string line in lines)
               {
                  if (line.StartsWith ("<H3>"))
                  {
                     refItem[0] = line.Substring (4, line.LastIndexOf ("</H3></TD></TR>") - 4);
                     nextTd = true;
                  }
                  else if (line.StartsWith ("<TD>") && nextTd)
                  {
                     refItem[1] = line.Substring (4, line.LastIndexOf ("</TD></TR>") - 4);
                     refList.Add (refItem);
                     refItem = new string[3];
                     nextTd = false;
                  }
               }

               if (refList.Count > 0)
               {
                  Thread t = new Thread (this.UpdateReferenceTexts);
                  t.Start (refList);
               }
            }
         }

      }

      /// <summary>
      /// Updates the Reference's text in the data base.
      /// </summary>
      /// <param name="refItems">List of Items</param>
      private void UpdateReferenceTexts (object refItems)
      {
        /*List<string[]> refList = (List<string[]>)refItems;

         if (refList.Count > 0)
         {
            bool dbHasChanges = false;
            Database db = new Database (refList[0][2]);
            Query qBookList = new Query (QueryType.SELECT, Common.TABLE_BOOK_LIST);
            qBookList.SELECT ("*");
            db.RunQuery (qBookList);
            foreach (string[] refItem in refList)
            {
               Query qSel = new Query (QueryType.SELECT);
               if (qBookList.RowsReturned == 1)
                  qSel.Table = qBookList.Results.GetFieldString (0, 0);
               else
                  qSel.Table = refItem[0][0].ToString ();
               qSel.SELECT ("Text");
               qSel.WHERE ("Word", Operator.EQUALS, refItem[0]);
               db.RunQuery (qSel);

               if (qSel.RowsReturned > 0)
               {
                  if (!qSel.Results.GetFieldString (0, 0).Equals (refItem[0]))
                  {
                     Query qUpdate = new Query (QueryType.UPDATE, qSel.Table);
                     qUpdate.SET ("Text", refItem[1]);
                     qUpdate.WHERE ("Word", Operator.EQUALS, refItem[0]);
                     db.RunQuery (qUpdate);
                     dbHasChanges = true;
                  }
               }
            }

            if (dbHasChanges)
               db.Commit ();
         }*/
      }

      /// <summary>
      /// Updates the Bible's text in the data base.
      /// </summary>
      /// <param name="verseList">List of Verses</param>
      private void UpdateBibleTexts (object verseList)
      {
         /*List<string[]> verses = (List<string[]>)verseList;

         Database db = null;
         string oldPath = "";
         bool dbHasChanges = false;
         foreach (string[] verse in verses)
         {
            if (oldPath != verse[2])
            {
               if (db != null && dbHasChanges)
               {
                  db.Commit ();
                  dbHasChanges = false;
               }

               db = new Database (verse[2]);
               oldPath = verse[2];
            }
            string[] parsedVerse = verse[0].Split ('|');
            Query q = new Query (QueryType.SELECT, parsedVerse[0]);
            q.SELECT ("Text");
            q.WHERE ("Chapter", Operator.EQUALS, parsedVerse[1]);
            q.WHERE ("Verse", Operator.EQUALS, parsedVerse[2]);
            db.RunQuery (q);
            if (q.RowsReturned > 0)
            {
               if (!q.Results.GetFieldString (0, 0).Equals (verse[1]))
               {
                  Query qUpdate = new Query (QueryType.UPDATE, parsedVerse[0]);
                  qUpdate.SET ("Text", verse[1]);
                  qUpdate.WHERE ("Chapter", Operator.EQUALS, parsedVerse[1]);
                  qUpdate.WHERE ("Verse", Operator.EQUALS, parsedVerse[2]);
                  db.RunQuery (qUpdate);
                  dbHasChanges = true;
               }
            }
         }
         if (db != null && dbHasChanges)
            db.Commit ();*/
      }

      #endregion
   }
}
